#include "HD44780SimulationDataGenerator.h"
#include "HD44780AnalyzerSettings.h"
#include <AnalyzerHelpers.h>
#include "PluginConstants.h"
#include "IDataGenerationCommand.h"
#include "GenInitSequenceCommand.h"
#include "GenTextCommand.h"
#include "HD4478011Bits.h"
#include "HD447807Bits.h"
#include "HD447808Bits.h"


HD44780SimulationDataGenerator::HD44780SimulationDataGenerator()
:	 mGenerateData(true)
{
}

HD44780SimulationDataGenerator::~HD44780SimulationDataGenerator()
{
    DeleteGenerators();
    DeleteCommands();
}


void HD44780SimulationDataGenerator::CreateSimulationChannelDescriptors()
{
    mData.clear();
	mDataMasks.clear();
	U32 count = mSettings->GetDefinedChannelsCount();
	for( U32 i=0; i<count; i++ )
	{
        if ( mSettings->GetDefinedChannel(i) != UNDEFINED_CHANNEL )
        {
            mData.push_back( mSimulationData.Add( mSettings->GetDefinedChannel(i), mSimulationSampleRateHz, BIT_LOW ) );
		    mDataMasks.push_back( 1 << i );	
        }
	}
}

void HD44780SimulationDataGenerator::Initialize( U32 simulation_sample_rate, HD44780AnalyzerSettings* settings )
{
	mSimulationSampleRateHz = simulation_sample_rate;
	mSettings = settings;
    CreateSimulationChannelDescriptors();
    DeleteGenerators();
    CreateGenerators();
    DeleteCommands();
    CreateCommands();
}


void  HD44780SimulationDataGenerator::CreateGenerators()
{
    mGenerators.push_back( new HD447807Bits() );     //  BITS7   = 0,
    mGenerators.push_back( new HD447808Bits() );     //  BITS8   = 1,
    mGenerators.push_back( new HD4478011Bits() );    //  BITS11  = 2, 
    CallStaticInitializerForGenerators();
}

void HD44780SimulationDataGenerator::CallStaticInitializerForGenerators() 
{
    IHD44780::Init(mSimulationSampleRateHz, mSettings, &mData, &mSimulationData );
}

void  HD44780SimulationDataGenerator::DeleteGenerators()
{
    int Size = mGenerators.size();
    for ( int i = 0; i < Size; ++i )
        delete mGenerators[i];
    mGenerators.clear();
}

void  HD44780SimulationDataGenerator::CreateCommands()
{
    mCommands.push_back( new GenInitSequenceCommand() );        // INITSEQUENCE = 0
    mCommands.push_back( new GenTextCommand() );                // BROWNFOX = 1
    mCommands.push_back( new GenTextCommand() );                // TEXTBOX=2
    CallStaticInitializerForCommands();
}

void  HD44780SimulationDataGenerator::CallStaticInitializerForCommands()
{
   IDataGenerationCommand::Init( mSettings, &mGenerators );
}

void  HD44780SimulationDataGenerator::DeleteCommands()
{
    int Size = mCommands.size();
    for ( int i = 0; i < Size; ++i )
        delete mCommands[i];
    mCommands.clear();
}

void HD44780SimulationDataGenerator::GenerateData() 
{
    mCommands[mSettings->GetDataGenerationMode()]->Generate();
    mGenerateData = false;
}


U32 HD44780SimulationDataGenerator::GenerateSimulationData( U64 largest_sample_requested, U32 sample_rate, SimulationChannelDescriptor** simulation_channel )
{
	U64 adjusted_largest_sample_requested = AnalyzerHelpers::AdjustSimulationTargetSample( largest_sample_requested, sample_rate, mSimulationSampleRateHz );
    if ( mGenerateData )
    {
        GenerateData();
    }
    else
    {
         mSimulationData.AdvanceAll( adjusted_largest_sample_requested );
    }

  	*simulation_channel = mSimulationData.GetArray();
	return mSimulationData.GetCount();
}



